#!/usr/bin/env node
const fs = require('fs');
const path = require('path');
const ts = require('typescript');

const componentName = process.argv[2];
if (!componentName) {
  console.error('Usage: node scripts/validate-config.js <ComponentName>');
  process.exit(1);
}

const ROOT = process.cwd();
const FIELDS_FILE = path.join(ROOT, 'src/components/editor/schema/fields/aiComponents.ts');
const EDIT_FILE = path.join(ROOT, 'src/components/editor/schema/edit/aiComponents.ts');

function readSource(file) {
  if (!fs.existsSync(file)) {
    throw new Error(`File not found: ${file}`);
  }
  const code = fs.readFileSync(file, 'utf8');
  return ts.createSourceFile(file, code, ts.ScriptTarget.ESNext, true, ts.ScriptKind.TS);
}

function getLiteralText(node) {
  if (!node) return undefined;
  if (ts.isStringLiteralLike(node) || ts.isNoSubstitutionTemplateLiteral(node)) {
    return node.text;
  }
  if (ts.isTemplateExpression(node) && node.head.text && node.templateSpans.length === 0) {
    return node.head.text;
  }
  return undefined;
}

function getPropertyName(name) {
  if (!name) return undefined;
  if (ts.isIdentifier(name) || ts.isStringLiteralLike(name)) {
    return name.text;
  }
  return undefined;
}

function checkFieldNode() {
  const sf = readSource(FIELDS_FILE);
  let found = null;

  function visit(node) {
    if (found) return;
    if (ts.isObjectLiteralExpression(node)) {
      const typeProp = node.properties.find(
        (prop) =>
          ts.isPropertyAssignment(prop) &&
          getPropertyName(prop.name) === 'type' &&
          ts.isStringLiteralLike(prop.initializer) &&
          prop.initializer.text === componentName,
      );
      if (typeProp) {
        found = node;
        return;
      }
    }
    ts.forEachChild(node, visit);
  }

  ts.forEachChild(sf, visit);

  if (!found) {
    throw new Error(`FieldNode entry for ${componentName} not found in ${FIELDS_FILE}`);
  }

  const moduleProp = found.properties.find(
    (prop) => ts.isPropertyAssignment(prop) && getPropertyName(prop.name) === 'module',
  );
  if (!moduleProp || !getLiteralText(moduleProp.initializer)) {
    throw new Error(`FieldNode ${componentName} requires a string literal module property`);
  }

  const propsProp = found.properties.find(
    (prop) => ts.isPropertyAssignment(prop) && getPropertyName(prop.name) === 'props',
  );
  if (!propsProp || !ts.isObjectLiteralExpression(propsProp.initializer)) {
    throw new Error(`FieldNode ${componentName} props must be an object literal`);
  }

  const propNames = [];
  propsProp.initializer.properties.forEach((prop) => {
    if (ts.isPropertyAssignment(prop)) {
      const name = getPropertyName(prop.name);
      if (name) propNames.push(name);
    }
  });

  if (!propNames.includes('visible')) {
    throw new Error(`FieldNode ${componentName} props must include "visible" field`);
  }

  return propNames;
}

function checkEditFields() {
  const sf = readSource(EDIT_FILE);
  let editArray = null;

  function visit(node) {
    if (editArray) return;
    if (ts.isPropertyAssignment(node)) {
      const name = getPropertyName(node.name);
      if (name === componentName && ts.isArrayLiteralExpression(node.initializer)) {
        editArray = node.initializer;
        return;
      }
    }
    ts.forEachChild(node, visit);
  }

  ts.forEachChild(sf, visit);

  if (!editArray) {
    throw new Error(`EditFields entry for ${componentName} not found in ${EDIT_FILE}`);
  }

  const missingKey = [];
  const missingBelongTo = [];

  editArray.elements.forEach((element, index) => {
    if (!ts.isObjectLiteralExpression(element)) return;
    const keyProp = element.properties.find(
      (prop) => ts.isPropertyAssignment(prop) && getPropertyName(prop.name) === 'key',
    );
    const belongToProp = element.properties.find(
      (prop) => ts.isPropertyAssignment(prop) && getPropertyName(prop.name) === 'belongTo',
    );
    if (!keyProp || !getLiteralText(keyProp.initializer)) {
      missingKey.push(index + 1);
    }
    if (!belongToProp || !getLiteralText(belongToProp.initializer)) {
      missingBelongTo.push(index + 1);
    }
  });

  if (missingKey.length) {
    throw new Error(`EditFields rows missing key: ${missingKey.join(', ')}`);
  }
  if (missingBelongTo.length) {
    throw new Error(`EditFields rows missing belongTo: ${missingBelongTo.join(', ')}`);
  }
}

function main() {
  try {
    checkFieldNode();
    checkEditFields();
    console.log(`✅ Config validation passed for ${componentName}`);
  } catch (error) {
    console.error(`❌ ${error.message || error}`);
    process.exit(1);
  }
}

main();
